/**
 * Food类
 */
class Food
{
    private int id;
    
    public Food (int id)
    {
        this.id = id;
    }
    
    public int getId ()
    {
        return id;
    }
}

/**
 * 缓冲区
 */
class SyncStack
{
    private Food[] foods = new Food[100];
    private int index;
    
    /**
     * 放食物
     */
    public synchronized void push(Food food) throws InterruptedException
    {
        while(index == foods.length)
        {
            /**
             * wait方法必须在synchronized方法块中运行
             * 让线程将持有的线程锁释放并进入阻塞状态
             * 其它要该线程锁的线程可以继续运行
             */
            this.wait();
        }
        
        /**
         * 同wait
         * 唤醒一个在等待的线程，线程重新进入运行状态
         */
        this.notify();
        
        this.foods[index] = food;
        index++;
    }
    
    /**
     * 取食物
     */
    public synchronized Food pop()
    {
        while(index == 0)
        {
            try
            {
                this.wait();
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        
        this.notify();
        
        index--;
        
        return this.foods[index];
    }
}

/**
 * 生产者
 */
class Produce extends Thread
{
    private SyncStack produce;
    
    public Produce (SyncStack produce)
    {
        this.produce = produce;
    }
    
    @Override
    public void run ()
    {
        for(int i = 0; i < 100; i++)
        {
            Food food = new Food(i);
            System.out.println("生产Foods" + food.getId());
            try
            {
                this.produce.push(food);
            }
            catch(InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }
}

/**
 * 消费者
 */
class Consumer extends Thread
{
    private SyncStack consumer;
    
    public Consumer (SyncStack consumer)
    {
        this.consumer = consumer;
    }
    
    @Override
    public void run ()
    {
        for(int i = 0; i < 100; i++)
        {
            Food food = this.consumer.pop();
    
            System.out.println("消费Food" + food.getId());
        }
    }
}

public class TestProductAndConsumer
{
    public static void main (String[] args)
    {
        //创建缓冲区
        SyncStack stack = new SyncStack();
        
        //创建生产者和消费者
        new Produce(stack).start();
        new Consumer(stack).start();
    }
}
